home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 8: LINUX Games
/
Linux Cubed Series 8 - LINUX Games.iso
/
games
/
x11
/
strategy
/
xpuzzles.3
/
xpuzzles
/
xpuzzles-5.3.1
/
xmball
/
xmball.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-02-05
|
11KB
|
376 lines
/*
# X-BASED MASTERBALL(tm)
#
# xmball.c
#
###
#
# Copyright (c) 1994 - 96 David Albert Bagley, bagleyd@hertz.njit.edu
#
# All Rights Reserved
#
# Permission to use, copy, modify, and distribute this software and
# its documentation for any purpose and without fee is hereby granted,
# provided that the above copyright notice appear in all copies and
# that both that copyright notice and this permission notice appear in
# supporting documentation, and that the name of the author not be
# used in advertising or publicity pertaining to distribution of the
# software without specific, written prior permission.
#
# This program is distributed in the hope that it will be "playable",
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
*/
/*
Version 1: 94/09/15 Xt
*/
#include <stdlib.h>
#include <stdio.h>
#ifdef VMS
#include <unixlib.h>
#define getlogin cuserid
#else
#ifndef apollo
#include <unistd.h>
#endif
#endif
#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <X11/Shell.h>
#include <X11/cursorfont.h>
#include "Mball.h"
#include "mball.xbm"
#ifndef SCOREFILE
#define SCOREFILE "/usr/games/lib/mball.scores"
#endif
/* The following are in MballP.h also */
#define MINWEDGES 2
#define MAXWEDGES 8
#define MINRINGS 1
#define MAXRINGS 6
#define MAXRECORD 32767
#define MAXPROGNAME 80
#define MAXNAME 256
static void Initialize();
static void CallbackMball();
static void PrintRecord();
static int HandleSolved();
static void PrintState();
static void ReadRecords();
static void WriteRecords();
static Arg arg[5];
static int mballRecord[2][(MAXWEDGES - MINWEDGES) / 2 + 1]
[MAXRINGS - MINRINGS + 1];
static int movesDsp = 0;
static char progDsp[64] = "xmball";
static char recordDsp[16] = "INF";
static char messageDsp[128] = "Welcome";
static char titleDsp[256] = "";
static void Usage()
{
(void) fprintf(stderr, "usage: xmball\n");
(void) fprintf(stderr,
"\t[-geometry [{width}][x{height}][{+-}{xoff}[{+-}{yoff}]]]\n");
(void) fprintf(stderr,
"\t[-display [{host}]:[{vs}]] [-fg {color}] [-bg {color}]\n");
(void) fprintf(stderr,
"\t[-{border|bd} {color}] [-mono] [-{wedges {int}}] [-{rings {int}}]\n");
(void) fprintf(stderr,
"\t[-[no]orient] [-[no]practice] [-wedge{0|1|2|3|4|5|6|7} {color}]\n");
exit(1);
}
static XrmOptionDescRec options[] = {
{"-fg", "*mball.Foreground", XrmoptionSepArg, NULL},
{"-bg", "*Background", XrmoptionSepArg, NULL},
{"-foreground", "*mball.Foreground", XrmoptionSepArg, NULL},
{"-background", "*Background", XrmoptionSepArg, NULL},
{"-border", "*mball.pieceBorder", XrmoptionSepArg, NULL},
{"-bd", "*mball.pieceBorder", XrmoptionSepArg, NULL},
{"-mono", "*mball.mono", XrmoptionNoArg, "TRUE"},
{"-wedges", "*mball.wedges", XrmoptionSepArg, NULL},
{"-rings", "*mball.rings", XrmoptionSepArg, NULL},
{"-orient", "*mball.orient", XrmoptionNoArg, "TRUE"},
{"-noorient", "*mball.orient", XrmoptionNoArg, "FALSE"},
{"-practice", "*mball.practice", XrmoptionNoArg, "TRUE"},
{"-nopractice", "*mball.practice", XrmoptionNoArg, "FALSE"},
{"-wedge0", "*mball.wedgeColor0", XrmoptionSepArg, NULL},
{"-wedge1", "*mball.wedgeColor1", XrmoptionSepArg, NULL},
{"-wedge2", "*mball.wedgeColor2", XrmoptionSepArg, NULL},
{"-wedge3", "*mball.wedgeColor3", XrmoptionSepArg, NULL},
{"-wedge4", "*mball.wedgeColor4", XrmoptionSepArg, NULL},
{"-wedge5", "*mball.wedgeColor5", XrmoptionSepArg, NULL},
{"-wedge6", "*mball.wedgeColor6", XrmoptionSepArg, NULL},
{"-wedge7", "*mball.wedgeColor7", XrmoptionSepArg, NULL},
};
int main(argc, argv)
int argc;
char *argv[];
{
Widget toplevel, mball;
toplevel = XtInitialize(argv[0], "Mball",
options, XtNumber(options), &argc, argv);
if (argc != 1)
Usage();
XtSetArg(arg[0], XtNiconPixmap,
XCreateBitmapFromData(XtDisplay(toplevel),
RootWindowOfScreen(XtScreen(toplevel)),
(char *) mball_bits, mball_width, mball_height));
XtSetValues(toplevel, arg, 1);
mball = XtCreateManagedWidget("mball", mballWidgetClass, toplevel,
NULL, 0);
XtAddCallback(mball, XtNselectCallback, CallbackMball, NULL);
Initialize(mball);
XtRealizeWidget(toplevel);
XGrabButton(XtDisplay(mball), AnyButton, AnyModifier, XtWindow(mball),
TRUE, ButtonPressMask | ButtonMotionMask | ButtonReleaseMask,
GrabModeAsync, GrabModeAsync, XtWindow(mball),
XCreateFontCursor(XtDisplay(mball), XC_crosshair));
XtMainLoop();
#ifdef VMS
return 1;
#else
return 0;
#endif
}
static void Initialize(w)
Widget w;
{
int wedges, rings;
Boolean orient, practice;
XtVaSetValues(w,
XtNstart, FALSE,
NULL);
XtVaGetValues(w,
XtNwedges, &wedges,
XtNrings, &rings,
XtNorient, &orient,
XtNpractice, &practice,
NULL);
ReadRecords();
PrintRecord(wedges, rings, orient, practice, recordDsp);
PrintState(XtParent(w), progDsp, wedges, rings, movesDsp,
recordDsp, messageDsp);
}
static void CallbackMball(w, clientData, callData)
Widget w;
caddr_t clientData;
mballCallbackStruct *callData;
{
int wedges, rings;
Boolean orient, practice, start;
XtVaGetValues(w,
XtNwedges, &wedges,
XtNrings, &rings,
XtNorient, &orient,
XtNpractice, &practice,
XtNstart, &start,
NULL);
(void) strcpy(messageDsp, "");
switch (callData->reason) {
case MBALL_RESTORE:
if (practice)
(void) strcpy(recordDsp, "practice");
movesDsp = 0;
break;
case MBALL_RESET:
movesDsp = 0;
break;
case MBALL_AMBIGUOUS:
(void) strcpy(messageDsp, "Ambiguous move");
break;
case MBALL_ILLEGAL:
if (practice || start)
(void) strcpy(messageDsp, "Illegal move");
else
(void) strcpy(messageDsp, "Randomize to start");
break;
case MBALL_MOVED:
movesDsp++;
XtSetArg(arg[0], XtNstart, TRUE);
XtSetValues(w, arg, 1);
break;
case MBALL_CONTROL:
return;
case MBALL_SOLVED:
if (practice)
movesDsp = 0;
else {
if (HandleSolved(movesDsp, wedges, rings, orient))
(void) sprintf(messageDsp, "Congratulations %s!!", getlogin());
else
(void) strcpy(messageDsp, "Solved!");
}
XtSetArg(arg[0], XtNstart, FALSE);
XtSetValues(w, arg, 1);
break;
case MBALL_PRACTICE:
movesDsp = 0;
practice = !practice;
if (!practice)
(void) strcpy(messageDsp, "Randomize to start");
PrintRecord(wedges, rings, orient, practice, recordDsp);
XtSetArg(arg[0], XtNpractice, practice);
XtSetArg(arg[1], XtNstart, FALSE);
XtSetValues(w, arg, 2);
break;
case MBALL_RANDOMIZE:
movesDsp = 0;
XtSetArg(arg[0], XtNpractice, FALSE);
XtSetArg(arg[1], XtNstart, FALSE);
XtSetValues(w, arg, 2);
break;
case MBALL_DEC:
movesDsp = 0;
rings--;
PrintRecord(wedges, rings, orient, practice, recordDsp);
XtSetArg(arg[0], XtNrings, rings);
XtSetValues(w, arg, 1);
break;
case MBALL_ORIENT:
movesDsp = 0;
orient = !orient;
PrintRecord(wedges, rings, orient, practice, recordDsp);
XtSetArg(arg[0], XtNorient, orient);
XtSetValues(w, arg, 1);
break;
case MBALL_INC:
movesDsp = 0;
rings++;
PrintRecord(wedges, rings, orient, practice, recordDsp);
XtSetArg(arg[0], XtNrings, rings);
XtSetValues(w, arg, 1);
break;
case MBALL_WEDGE2:
case MBALL_WEDGE4:
case MBALL_WEDGE6:
case MBALL_WEDGE8:
movesDsp = 0;
wedges = 2 * (callData->reason - MBALL_WEDGE2) + MINWEDGES;
PrintRecord(wedges, rings, orient, practice, recordDsp);
XtSetArg(arg[0], XtNwedges, wedges);
XtSetValues(w, arg, 1);
break;
case MBALL_COMPUTED:
XtSetArg(arg[0], XtNstart, FALSE);
XtSetValues(w, arg, 1);
break;
case MBALL_UNDO:
movesDsp--;
XtSetArg(arg[0], XtNstart, TRUE);
XtSetValues(w, arg, 1);
break;
}
PrintState(XtParent(w), progDsp, wedges, rings, movesDsp,
recordDsp, messageDsp);
}
static void PrintRecord(wedges, rings, orient, practice, record)
int wedges, rings;
Boolean orient, practice;
char *record;
{
int i = (orient) ? 1 : 0;
int w = (wedges - MINWEDGES) / 2;
int r = rings - MINRINGS;
if (practice)
(void) strcpy(record, "practice");
else if (rings > MAXRINGS)
(void) strcpy(record, "NOT RECORDED");
else if (mballRecord[i][w][r] >= MAXRECORD)
(void) strcpy(record, "NEVER");
else
(void) sprintf(record, "%d", mballRecord[i][w][r]);
}
static int HandleSolved(counter, wedges, rings, orient)
int counter, wedges, rings;
Boolean orient;
{
int i = (orient) ? 1 : 0;
int w = (wedges - MINWEDGES) / 2;
int r = rings - MINRINGS;
if (rings <= MAXRINGS && counter < mballRecord[i][w][r]) {
mballRecord[i][w][r] = counter;
if (orient && mballRecord[i][w][r] < mballRecord[!i][w][r])
mballRecord[!i][w][r] = counter;
WriteRecords();
(void) sprintf(recordDsp, "%d", counter);
return TRUE;
}
return FALSE;
}
static void PrintState(w, prog, wedges, rings, moves, record, message)
Widget w;
char *prog, *record, *message;
int wedges, rings, moves;
{
(void) sprintf(titleDsp, "%s.%d: %d@ (%d/%s) - %s", prog, wedges, rings,
moves, record, message);
XtSetArg(arg[0], XtNtitle, titleDsp);
XtSetValues(w, arg, 1);
}
static void ReadRecords()
{
FILE *fp;
int i, j, n, orient;
for (orient = 0; orient < 2; orient++)
for (i = 0; i < (MAXWEDGES - MINWEDGES) / 2 + 1; i++)
for (j = 0; j < MAXRINGS - MINRINGS + 1; j++)
mballRecord[orient][i][j] = MAXRECORD;
if ((fp = fopen(SCOREFILE, "r")) == NULL)
(void) sprintf(messageDsp, "Can not open %s, taking defaults.", SCOREFILE);
else {
for (orient = 0; orient < 2; orient++)
for (i = 0; i < (MAXWEDGES - MINWEDGES) / 2 + 1; i++)
for (j = 0; j < MAXRINGS - MINRINGS + 1; j++) {
(void) fscanf(fp, "%d", &n);
mballRecord[orient][i][j] = n;
}
(void) fclose(fp);
}
}
static void WriteRecords()
{
FILE *fp;
int i, j, orient;
if ((fp = fopen(SCOREFILE, "w")) == NULL)
(void) sprintf(messageDsp, "Can not write to %s.", SCOREFILE);
else {
for (orient = 0; orient < 2; orient++) {
for (i = 0; i < (MAXWEDGES - MINWEDGES) / 2 + 1; i++) {
for (j = 0; j < MAXRINGS - MINRINGS + 1; j++)
(void) fprintf(fp, "%d ", mballRecord[orient][i][j]);
(void) fprintf(fp, "\n");
}
(void) fprintf(fp, "\n");
}
(void) fclose(fp);
}
}